package com.xuzhijie.pms.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.DeleteBatchByIds;
import com.baomidou.mybatisplus.core.injector.methods.DeleteById;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuzhijie.pms.common.Constants;
import com.xuzhijie.pms.common.Result;
import com.xuzhijie.pms.entity.Administrator;
import com.xuzhijie.pms.entity.Role;
import com.xuzhijie.pms.entity.dto.AdministratorDto;
import com.xuzhijie.pms.entity.vo.AdministratorVo;
import com.xuzhijie.pms.exception.PmsServerException;
import com.xuzhijie.pms.mapper.AdministratorMapper;
import com.xuzhijie.pms.mapper.RoleMapper;
import com.xuzhijie.pms.service.IAdministratorService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuzhijie.pms.utils.JwtUtils;
import com.xuzhijie.pms.utils.ThreadLocalUtil;
import com.xuzhijie.pms.utils.saltUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.coyote.http11.filters.IdentityInputFilter;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 许志杰
 * @since 2024-02-05
 */
@Service
@Slf4j
@Transactional
public class AdministratorServiceImpl extends ServiceImpl<AdministratorMapper, Administrator> implements IAdministratorService {


    @Resource
    private AdministratorMapper administratorMapper;

    @Resource
    private RoleMapper roleMapper;

    /***
     * 登录方法
     * @param dto
     */
    @Override
    public Result login(AdministratorDto dto) {
        System.out.println(dto.getAccount()+dto.getPassword());
        String account = dto.getAccount();
        if (StrUtil.isBlank(account)){
           return Result.error(Constants.CODE_600,"用户不存在");
        }
        QueryWrapper<Administrator> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account",account);
        Administrator one = getOne(queryWrapper);
        if (one == null){
            return Result.error(Constants.CODE_600,"用户不存在");
        }
        String encodePassword = saltUtil.encodePassword(dto.getPassword(), one.getSalt());
        log.info("密码为："+dto.getPassword());
        log.info("加密为："+one.getSalt());
        log.info("加密后为："+encodePassword);
        log.info("数据库为："+one.getPassword());
        if (!one.getPassword().equals(encodePassword)){
            return Result.error(Constants.CODE_600,"密码错误");
        }

        //登录成功，生成token
        String token = JwtUtils.generateToken(one.getId(), one.getSalt());
        BeanUtils.copyProperties(one,dto);
        dto.setToken(token);
        dto.setPassword("");
        String dtoStr = JSONUtil.toJsonStr(dto);
        return Result.success(dtoStr);
    }

    // 查询分页 TODO 有时间集成redis
    @Override
    public Result findPage(Integer page,
                           Integer size,
                           String name,
                           String phone,
                           String status,
                           Date startTime,
                           Date endTime) {
        Page<Administrator> pages = new Page<>(page,size);
        Page<Administrator> administratorPage;
        long total;

        //校验参数
        QueryWrapper<Administrator> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isDelete",0);
        if (StrUtil.isNotBlank(name)){
            queryWrapper.like("name",name);
        }
        if (StrUtil.isNotBlank(phone)){
            queryWrapper.eq("mobile",phone);
        }
        if (StrUtil.isNotBlank(status)){
            queryWrapper.eq("status", NumberUtil.parseInt(status));
        }
        if (startTime != null && endTime != null){
            queryWrapper.between("create_time",startTime,endTime);
        }
            queryWrapper.orderByAsc("create_time");
        try{
            administratorPage  = administratorMapper.selectPage(pages,queryWrapper);
            total = count(queryWrapper);
        }catch (Exception e){
            e.printStackTrace();
            throw new PmsServerException("业务繁忙",Constants.SYSTEM_ERROR);
        }

        List<Administrator> records = administratorPage.getRecords();
        List<AdministratorVo> voList = new ArrayList<>();
        for (Administrator record : records) {
            AdministratorVo vo = new AdministratorVo();
            BeanUtils.copyProperties(record,vo);
            if (record.getAuthority() == 1){
                vo.setAuthority("超级管理员");
            }else if (record.getAuthority() == 2){
                vo.setAuthority("管理员");
            }
            if (record.getStatus() == 1){
                vo.setStatus(true);
            }else{
                vo.setStatus(false);
            }
            voList.add(vo);
        }

        Map<String,Object> result = new HashMap<>();
        result.put("records",voList);
        result.put("total",total);

        System.out.println(result);
        return Result.success(result);
    }


    @Override
    public Result editAdmin(AdministratorVo vo) {
        Administrator admin = getById(vo.getId());
        BeanUtils.copyProperties(vo,admin);
        if (vo.getAuthority().equals("超级管理员")){
            admin.setAuthority(2);
        }
        if (vo.getStatus() == true){
            admin.setStatus(1);
        }else{
            admin.setStatus(0);
        }
        admin.setUpdateTime(LocalDateTime.now());
        QueryWrapper<Administrator> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",vo.getId());
        update(admin,queryWrapper);

        AdministratorVo newVo = new AdministratorVo(admin.getStatus(), admin.getAuthority());
        BeanUtils.copyProperties(admin,newVo);

        return Result.success(newVo);
    }

    @Override
    public Result deleteAdmin(String[] ids) {
        HashSet<String> set = new HashSet<>(Arrays.asList(ids));
        int deleteNumber = administratorMapper.deleteBatchIds(set);
        return Result.success(deleteNumber);
    }

    @Override
    public Result createAdmin(String name, String phone, String password, String id,String roleId ) {
        Administrator admin = getById(id);
        if (BeanUtil.isEmpty(admin)){
            return Result.error();
        }
        String salt = admin.getSalt();
        String encodePassword = saltUtil.encodePassword(password, salt);
        if (!admin.getPassword().equals(encodePassword)){
            return Result.error(Constants.CODE_600,"密码验证失败");
        }
        String newSalt = saltUtil.generateSalt();
        Administrator administrator = new Administrator();
        administrator.setAccount(RandomUtil.randomNumbers(6));
        administrator.setPassword(saltUtil.encodePassword("123456",newSalt));
        administrator.setName(name);
        administrator.setSalt(newSalt);
        administrator.setMobile(phone);
        administrator.setAuthority(Integer.parseInt(roleId));
        int insert = administratorMapper.insert(administrator);


        return Result.success(insert);
    }

    @Override
    public Result getAdminById(String id) {
        Administrator admin = getById(id);
        Map<String, Object> map = new HashMap<>();
        if (admin!=null){
            AdministratorDto dto = new AdministratorDto();
            BeanUtil.copyProperties(admin,dto);
            int authority = dto.getAuthority();
            Role role = roleMapper.selectById(authority);
            map.put("role",role);
            map.put("admin",dto);
            return Result.success(map);
        }
        return Result.error();
    }

    @Override
    public Result changePassword(Map<String, Object> request) {
        String oldPassword = request.get("oldPassword").toString();
        String newPassword = request.get("newPassword").toString();
        String repeatPassword = request.get("repeatPassword").toString();

        Administrator currentUser = ThreadLocalUtil.getCurrentUser();
        String salt = currentUser.getSalt();
        String password = saltUtil.encodePassword(oldPassword, salt);
        if (!password.equals(currentUser.getPassword())){
            return Result.error(Constants.ILLEGAL_PARAMETERS,"旧密码错误");
        }
        if (!newPassword.equals(repeatPassword)){
            return Result.error(Constants.ILLEGAL_PARAMETERS,"两次密码不一致");
        }

        String password1 = saltUtil.encodePassword(newPassword, salt);
        currentUser.setPassword(password1);

        saveOrUpdate(currentUser);
        return Result.success();
    }


}
